package org.sean.framework.bean;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * 分页响应
 *
 * @param <T> T
 * @author sean.xie
 */
@Schema(description = "分页响应信息")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PageData<T> {
    @Schema(description = "总条数")
    @Builder.Default
    private long count = 0;
    @Schema(description = "页码")
    @Builder.Default
    private long page = 1;
    @Schema(description = "每页条数")
    private long size;
    @Schema(description = "数据列表")
    @Builder.Default
    private List<T> list = new ArrayList<>();

    /**
     * 分页处理
     *
     * @param req 分页条件
     * @param fun 所有符合条件的数据
     * @param <T> 返回值的数据类型
     * @param <P> 参数的数据类型
     * @return 分页数据
     */
    public static <T, P extends PageQuery> PageData<T> paging(P req, Function<P, List<T>> fun) {
        PageData<T> result = new PageData<>();
        List<T> scores = fun.apply(req);
        if (scores.isEmpty()) {
            return result;
        }
        result.count = scores.size();
        if (scores.size() < req.getOffset()) {
            return result;
        }
        int end = req.getOffset() + req.getLimit();
        // 大于最大数量
        if (scores.size() < end) {
            end = scores.size();
        }
        result.setPage(req.getPage());
        result.setSize(req.getSize());
        result.setList(scores.subList(req.getOffset(), end));
        return result;
    }

    /**
     * 分页
     *
     * @param req    分页信息
     * @param scores 列表
     * @param <T>    元素类型
     * @return 分页数据
     */
    public static <T> PageData<T> paging(PageQuery req, List<T> scores) {
        return paging(req, req.getOffset(), req.getLimit(), scores);
    }

    /**
     * 分页
     *
     * @param offset 开始位置
     * @param limit  条数
     * @param scores 源数据
     * @param <T>    元素类型
     * @return 分页数据
     */
    private static <T> PageData<T> paging(PageQuery req, int offset, int limit, List<T> scores) {
        PageData<T> result = new PageData<>();
        if (scores.isEmpty()) {
            return result;
        }
        result.count = scores.size();
        if (scores.size() < offset) {
            return result;
        }
        int end = offset + limit;
        // 大于最大数量
        if (scores.size() < end) {
            end = scores.size();
        }
        result.setSize(req.getSize());
        result.setPage(req.getPage());
        result.setList(scores.subList(offset, end));
        return result;
    }

}

